package com.boyicloud.exchangeserver.security

import com.boyicloud.exchangeserver.common.ResponseUtil
import com.boyicloud.exchangeserver.common.Result
import com.boyicloud.exchangeserver.common.TokenManager
import com.boyicloud.exchangeserver.domain.User
import com.fasterxml.jackson.databind.ObjectMapper
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springframework.security.authentication.AuthenticationManager
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken
import org.springframework.security.core.Authentication
import org.springframework.security.core.AuthenticationException
import org.springframework.security.core.userdetails.UsernameNotFoundException
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter
import org.springframework.security.web.util.matcher.AntPathRequestMatcher
import java.io.IOException
import javax.servlet.FilterChain
import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse

class LoginAuthFilter(authenticationManager: AuthenticationManager, private val tokenManager: TokenManager) :
    UsernamePasswordAuthenticationFilter() {

    val log: Logger = LoggerFactory.getLogger(LoginAuthFilter::class.java)

    init {
        this.authenticationManager = authenticationManager
        this.setPostOnly(true)
        this.setRequiresAuthenticationRequestMatcher(AntPathRequestMatcher("/user/login", "POST"))
    }


    override fun attemptAuthentication(request: HttpServletRequest, response: HttpServletResponse): Authentication {
        try {
            val loginUser = ObjectMapper().readValue(request.inputStream, User::class.java)
            return authenticationManager.authenticate(
                UsernamePasswordAuthenticationToken(
                    loginUser.username, loginUser.password,
                    listOf()
                )
            )
        } catch (e: IOException) {
            log.warn("[登录校验]读取登录信息出错，错误信息: ${e.message}", e)
            throw  UsernameNotFoundException("账户不存在")
        }
    }


    override fun successfulAuthentication(
        request: HttpServletRequest,
        response: HttpServletResponse,
        chain: FilterChain,
        authResult: Authentication
    ) {
        ResponseUtil.out(response, Result(data = User().apply {
            username = authResult.name
            token = tokenManager.createToken(authResult.name)
        }))
    }

    override fun unsuccessfulAuthentication(
        request: HttpServletRequest?,
        response: HttpServletResponse,
        failed: AuthenticationException?
    ) {
        ResponseUtil.out(
            response,
            Result(success = false, data = "", errMessage = "用户或密码错误")
        )

    }
}